
import Konva from 'konva'
import { NodeTwo, NodeOne, createArrowLine, generate, createText } from './node'
import { showFn, useColor, addEvt, activeRectFn } from './show'
import { decompressFromUTF16 } from 'lz-string'

const cuMap = {
  't1': '/ic/t12.png',
  't2-1': '/ic/t2-1.png',
  't2-2': '/ic/t2-2.png',
  't2-3': '/ic/t2-3.png'
}

/**
 * 创建流程，
 * @param {string} id -容器id选择器
 */
export const createFD = (id) => {
  const internalAttributes = {
    toolActive: '',
    onToolActiveFn: (item) => {},
    onCurrentShapeFn: (item) => {},
    update: () => {},
    generate: () => {},
    clear: () => {}
  }

  const dom = document.getElementById(id)
  if (!dom) {
    console.error(`id:${id} ,元素不存在`)
    return
  }
  dom.style.position = 'relative'

  /** @type {Konva.Stage} */
  let stage = null

  const init = () => {
    stage = new Konva.Stage({
      x: 0,
      y: 0,
      name: 'stage',
      container: id,
      width: dom.clientWidth,
      height: dom.clientHeight,
      draggable: true
    })
    const layer = new Konva.Layer({ id: 'layer' })
    stage.add(layer)
    stage.setCurrent = (item) => {
      internalAttributes.onCurrentShapeFn(item)
    }

    internalAttributes.update = (node) => {
      node.update()
    }
    internalAttributes.generate = generate(stage)
    internalAttributes.clear = () => {
      stage.destroy()
      stage.off()
      dom.innerHTML = ''
      stage = null
      init()
    }

    mouseStyle(stage, dom, internalAttributes)
  }

  init()

  return internalAttributes
}

/**
 * 鼠标进入画布，如果有激活工具选项则改变鼠标样式
 * @param { import('konva').default.Stage } stage
 * @param { HTMLElement } dom
 * @param { { toolActive: string } } internalAttributes
 */
const mouseStyle = (stage, dom, internalAttributes) => {
  const img = document.createElement('img')
  img.style.position = 'absolute'
  img.style.top = '0px'
  img.style.left = '0px'
  img.style.height = '32px'
  img.style.opacity = 0.5
  img.style.pointerEvents = 'none'

  const layer = stage.findOne('#layer')

  // 箭头线绘制时需要的group
  const arrowGroup = new Konva.Group({
    id: 'arrowGroup'
  })

  layer.add(arrowGroup)

  const move = (e) => {
    const { offsetX, offsetY } = e.evt
    img.style.left = offsetX + 'px'
    img.style.top = offsetY + 'px'
  }

  stage.on('mouseenter', () => {
    const att = internalAttributes.toolActive
    if (att && cuMap[att]) {
      img.src = cuMap[att]
      img.style.opacity = 0.5
      dom.appendChild(img)
      stage.on('mousemove', move)
    }
  })

  stage.on('mouseleave', () => {
    img.style.opacity = 0
  })

  stage.on('click', e => {
    const att = internalAttributes.toolActive
    if (att) {
      const { offsetX, offsetY } = e.evt
      const x = offsetX - stage.x()
      const y = offsetY - stage.y()

      if (cuMap[att]) {
        dom.removeChild(img)
        stage.off('mousemove', move)

        let g1 = new NodeTwo({
          x,
          y,
          h: 36,
          w: 36,
          img: cuMap[att],
          txt: 'xxx'
        })

        if (att === 't1') {
          g1 = new NodeOne({
            x,
            y,
            h: 40,
            img: cuMap[att],
            txt: '标题'
          })
        }

        layer.add(g1)
        layer.batchDraw()

        internalAttributes.toolActive = ''
        internalAttributes.onToolActiveFn('')
      }

      if (att == 'a1') {
        //
        createArrowLine(stage, { x, y, call: () => {
          internalAttributes.toolActive = ''
          internalAttributes.onToolActiveFn('')
        } })
      }
      if (att == 'a2') {
        createText(stage, { x, y, call: () => {
          internalAttributes.toolActive = ''
          internalAttributes.onToolActiveFn('')
        } })
      }
    }
  })
}
// import json from './test2.json'

/**
 * @param { string } id - 容器id选择器
 * @param { object } [data] - 流程数据，用于还原为序列图形
 */
export const createFDByData = (id, data) => {
  const dom = document.getElementById(id)
  if (!dom) {
    console.error(`id:${id} ,元素不存在`)
    return
  }
  dom.style.position = 'relative'

  /** @type {Konva.Stage} */
  let stage = null

  // 图中横向箭头的长度
  const interval = 100

  /** 向外暴露的方法属性 */
  const ref = {
    /** 激活节点 */
    onActive: (node) => {}
  }

  /** 根据数据绘制图形或更新图形 */
  const draw = async(data) => {
    // console.log('data', data)

    if (stage) {
      stage.destroy()
    }
    const json = data?.nodeJson
    if (json) {
      stage = Konva.Node.create(decompressFromUTF16(json), id)
      const r = await showFn(stage)
      stage.findOne('Layer').draw()
      console.log('r', r)
    } else {
      stage = new Konva.Stage({
        x: 0,
        y: 0,
        name: 'stage',
        container: id,
        width: dom.clientWidth,
        height: dom.clientHeight,
        draggable: true
      })
      const layer = new Konva.Layer({ id: 'layer' })
      stage.add(layer)

      const task = []

      data.sceneParentNodeManagerList.forEach((i, index) => {
        const node1 = new NodeOne({
          x: 60,
          y: 50 + index * 100,
          h: 40,
          img: '/ic/t12.png',
          txt: i.nodeName || '标题',
          id: i.nodeId,
          onlyShow: true,
          onFinish: (np) => {
            task.push(np)
          }
        })
        layer.add(node1)
        const { x, y } = node1.getAbsolutePosition(stage)
        const { width, height } = node1.getClientRect()
        const h1 = height / 2 - 5
        if (index > 0) {
          const x1 = x + 60
          const arrow = new Konva.Arrow({
            points: [x1, y - 55, x1, y - 8],
            stroke: '#29eeff',
            fill: '#29eeff',
            strokeWidth: 1,
            lineCap: 'round',
            lineJoin: 'round',
            dash: [2, 2]
          })
          layer.add(arrow)
        }
        let left = x + width + interval

        i.sceneChildNodeManagerList.forEach((j, idx) => {
          const node2 = new NodeTwo({
            x: left,
            y: 46 + index * 100,
            w: 36,
            h: 36,
            img: '/ic/t2-1.png',
            txt: j.childNodeName || 'xxx',
            id: j.nodeId,
            onlyShow: true,
            onFinish: (np) => {
              task.push(np)
            }
          })
          layer.add(node2)

          const arrow = new Konva.Arrow({
            points: [left - interval + 5, y + h1, left - 5, y + h1],
            stroke: '#29eeff',
            fill: '#29eeff',
            strokeWidth: 1,
            lineCap: 'round',
            lineJoin: 'round',
            dash: [2, 2]
          })
          layer.add(arrow)
          left += interval + 36
        })
      })

      const c = await Promise.allSettled(task)
      console.log('c111', c)
    }

    useColor(stage, data)
    addEvt(stage, data, ref)
  }

  if (data) {
    draw(data)
  }

  /** 更新图形中状态（对应颜色和标签变化） */
  const updateStatus = (data) => {
    if (stage) {
      useColor(stage, data)
    }
  }

  /** 激活图形添加紫色矩形框 */
  const updateActiveRect = (id) => {
    activeRectFn(stage, id)
  }

  return {
    updateActiveRect,
    updateStatus,
    draw,
    ref
  }
}
